/* COMBINE is a small module giving combination
   for a given size   (maths C n;p )

   the process start with p highest positions set to 1
   and finish with p lowest positions sets to 
   the lowest digit goes down till the lowest position, then the next ...

*/
#define _CRT_SECURE_NO_DEPRECATE

//#include <fstream>
//#include <iostream>
//#include <stdio.h>
#include <stdlib.h>
using namespace std;
#include "v2skfrtype.h"

#include "v2utilities.h"
#include "v2sk_tables.cpp"


//=============================
//====================== to be in line with borland string 
char * stpcpy(char * d, const char * o)
	{strcpy(d,o); return (d+strlen(d));}

char * Blancs(int n,int pastrait)
 {static char wt[]="___________________ ",
              wn[]="                    ";
              if(pastrait)return &wn[20-n]; else return &wt[20-n];}

int CELL_FIX::GetTableRegions(USHORT * tt,CELL_FIX & cell2){
	int n=0;
	if(el==cell2.el) tt[n++]=el;
	if(pl==cell2.pl) tt[n++]=plu;
	if(eb==cell2.eb) tt[n++]=ebu;
	return n;
}



/* First is the initial call for the task
   n;p is the classical math sense

   n total number of objects
   p number of object to select (maxi is p=10)

   d in the entry table
   f is the result table  both size n
*/
 
 void COMBINE::First(int ne,int pe,USHORT * d, USHORT * f )    {
	 entry=d; 
	 output=f;   
	 p=pe;  
	 if(p>10)
		 p=10;  // safety measure, not auhorised
	 lim=p-1; 
	 n=ne;
     for(UINT i=0,v=n-p;i<p;i++,v++) 
		 inds[i]=v;
     Sort();
 }
 /* move step by step from p upper index to p lower index
    return 1 if ok;  0 if over
 */
 int COMBINE::Next()  {
	 if(inds[lim]==lim) 
		 return 0; // finished
     int i=0; 
	 while(inds[i]==i) 
		 i++; // lock for first that can go down
	 inds[i]--; // back one for that one
	 UINT v=inds[i];  // an restart below with no hole
	 while(i--) inds[i]=--v;
	 Sort();    
	 return 1;}

/* send back the entry table with first p as the selection
   others after the selection
   inds is the list of "p" index selected
*/

 void COMBINE::Sort()   { 
	 UINT is=0,js=n-p,jns=0;
	 for(UINT i=0;i<n;i++) {
		 if(i-inds[is] ){
		   output[jns++]=entry[i]; 
		   continue;
		}
	    output[js++]=entry[i];
		if(is<p-1)   // don't pass the limit of the table inds
			is++;   
	 }   

 }  

                //=============== PUZ0

 void PUZ0::Create(char * ze){
	 for(int i=0;i<81;i++){
		 char c=ze[i];
		 if(c>'0' && c<='9')
			 puz[i]=c-'0';
		 else
			puz[i]=0;
	 }
 }

 void PUZ0::Empty(){
	 for(int i=0;i<81;i++)
		 puz[i]=0;	
 }

char * PUZ0::String(char * zout){
	 for(int i=0;i<81;i++)
		 if(puz[i])
			zout[i]=puz[i]+'0';
		 else
			 zout[i]='.';
	 zout[81]=0;
	 return zout;
}

                //=============== PUZC

 void PUZC::Create(char * ze){
	 for(int i=0;i<81;i++){
		 char c=ze[i];
		 if(c>'0' && c<='9')
			 puz[i]=c;
		 else
			 puz[i]='.';
	 }
	 puz[81]=0;
 }

 void PUZC::CreateFromZeroBased(char * ze){
	 for(int i=0;i<81;i++){
		 char c=ze[i];
		 if(c)
			 puz[i]=c+'0';
		 else
			 puz[i]='.';
	 }
	 puz[81]=0;
 }



GG::GG() {	// constructor
	pg = g[0]; 
	pg[81] = 0;
}

int GG::NBlancs() const {
	int i, n = 0;
	for(i = 0; i < 81; i++)
		if(pg[i] == '.')
			n++;   
	return n;
}

int GG::Nfix() const {
	int i, n = 0; 
	for(i = 0; i < 81; i++) 
		if(pg[i] - '.')
			n++;   
	return n;
}




int DIVF::IsObjetI(BF81 const &ze, int i) {
	return (ze.EstDans(cellsInHouseBM[i]));
}

int DIVF::IsObjet(const BF81 &ze) {
	for(int i = 0; i < 27; i++)
		if(IsObjetI(ze, i)) 
			return 1;  
	return 0;
}

int DIVF::IsBox(const BF81 &ze) {
	for(int i = 18; i < 27; i++) 
		if(IsObjetI(ze, i))
			return i; 
	return 0;
} 

int DIVF::IsObjet(USHORT p1, USHORT p2) {
	BF81 z(p1, p2);
	return IsObjet(z);
}

int DIVF::IsAutreObjet(const BF81 &ze, int obje, int &objs) {
	for(int i = 0; i < 27; i++) {
		if(i == obje)
			continue;
		if(IsObjetI(ze, i)) {
			objs=i;
			return 1; 
		}
	}
	return 0;
}
	//! Get valued cell count in the house <code>el</code>
int DIVF::N_Fixes(const char * pg, int el) {
	int n = 0; 
	for(int i = 0; i < 9; i++) 
		if(pg[cellsInGroup[el][i]] - '0')
			n++;
	return n;
}




 